package com.mcc.app.group.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mcc.app.group.domain.GroupClasses;
import com.mcc.app.group.domain.GroupSche;
import com.mcc.app.group.dto.GroupScheAutoDTO;
import com.mcc.app.group.dto.GroupScheBatchDTO;
import com.mcc.app.group.mapper.GroupScheMapper;
import com.mcc.app.group.service.IGroupClassesService;
import com.mcc.app.group.service.IGroupScheService;
import com.mcc.app.group.service.IGroupTeamService;
import com.mcc.common.exception.CustomException;
import com.mcc.system.domain.SysConfig;
import com.mcc.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 排班计划Service业务层处理
 *
 * @author gxy
 * @date 2021-07-08
 */
@Service
public class GroupScheServiceImpl implements IGroupScheService {

    @Autowired
    private GroupScheMapper groupScheMapper;

    @Autowired
    private IGroupClassesService groupClassesService;

    @Autowired
    private IGroupTeamService groupTeamService;

    @Autowired
    private ISysConfigService sysConfigService;

    /**
     * 查询排班计划
     *
     * @param scheId 排班计划ID
     * @return 排班计划
     */
    @Override
    public GroupSche selectGroupScheById(Long scheId) {
        return groupScheMapper.selectById(scheId);
    }

    /**
     * 查询排班计划列表
     *
     * @param groupSche 排班计划
     * @return 排班计划
     */
    @Override
    public List<GroupSche> selectGroupScheList(GroupSche groupSche) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (ObjectUtil.isNotEmpty(groupSche)) {
            queryWrapper.eq(ObjectUtil.isNotEmpty(groupSche.getScheDate()), "sche_date", groupSche.getScheDate());
            queryWrapper.eq(ObjectUtil.isNotEmpty(groupSche.getClassesId()), "classes_id", groupSche.getClassesId());
            queryWrapper.eq(ObjectUtil.isNotEmpty(groupSche.getTeamId()), "team_id", groupSche.getTeamId());
            queryWrapper.ge(ObjectUtil.isNotEmpty(groupSche.getSearchStartDate()), "sche_date", groupSche.getSearchStartDate());
            queryWrapper.le(ObjectUtil.isNotEmpty(groupSche.getSearchEndDate()), "sche_date", groupSche.getSearchEndDate());
        }
        queryWrapper.orderByAsc("start_dt");
        List<GroupSche> res = groupScheMapper.selectList(queryWrapper);
        for (int i = 0; i < res.size(); i++) {
            GroupSche row = res.get(i);
            row.setClasses(groupClassesService.selectGroupClassesById(row.getClassesId()));
            row.setTeam(groupTeamService.selectGroupTeamById(row.getTeamId()));
        }
        return res;
    }

    /**
     * 新增排班计划
     *
     * @param groupSche 排班计划
     * @return 结果
     */
    @Override
    public int insertGroupSche(GroupSche groupSche) {
        return groupScheMapper.insert(groupSche);
    }

    /**
     * 修改排班计划
     *
     * @param groupSche 排班计划
     * @return 结果
     */
    @Override
    public int updateGroupSche(GroupSche groupSche) {
        return groupScheMapper.updateById(groupSche);
    }

    /**
     * 删除排班计划
     *
     * @param scheId 排班计划ID
     * @return 结果
     */
    @Override
    public int deleteGroupScheById(Long scheId) {
        return groupScheMapper.deleteById(scheId);
    }

    /**
     * 批量删除排班计划
     *
     * @param scheIds 排班计划ID
     * @return 结果
     */
    @Override
    public int deleteGroupScheByIds(Long[] scheIds) {
        if (scheIds.length == 0) return 0;
        return groupScheMapper.deleteBatchIds(ListUtil.toList(scheIds));
    }

    @Override
    public boolean checkGroupSche(GroupSche groupSche) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("sche_date", groupSche.getScheDate());
        queryWrapper.eq("classes_id", groupSche.getClassesId());
        queryWrapper.ne(ObjectUtil.isNotEmpty(groupSche.getScheId()), "sche_id", groupSche.getScheId());
        return groupScheMapper.selectCount(queryWrapper) == 0;
    }

    @Override
    public void calTimeGroupSche(GroupSche groupSche) {
        GroupClasses groupClasses = null;
        if (groupSche.getClassesId() != null) {
            groupClasses = groupClassesService.selectGroupClassesById(groupSche.getClassesId());
        }
        if (groupSche.getClassesName() != null) {
            groupClasses = groupClassesService.selectGroupClassesByName(groupSche.getClassesName());
        }
        if (groupClasses == null) return;
        if (groupClasses == null) return;
        if (StrUtil.isEmpty(groupClasses.getStartTime())) return;
        if (StrUtil.isEmpty(groupClasses.getEndTime())) return;

        Date startDt = DateUtil.parseDateTime(DateUtil.formatDate(groupSche.getScheDate()) + " " + groupClasses.getStartTime());
        Date endDt = DateUtil.parseDateTime(DateUtil.formatDate(groupSche.getScheDate()) + " " + groupClasses.getEndTime());
        if (startDt.getTime() > endDt.getTime()) {
//            endDt = DateUtil.offset(endDt, DateField.DAY_OF_MONTH, 1);
            startDt = DateUtil.offset(startDt, DateField.DAY_OF_MONTH, -1);
        }
        groupSche.setStartDt(startDt);
        groupSche.setEndDt(endDt);
    }

    @Override
    public void calTimeGroupSche(GroupSche groupSche, Date nowDt) {
        GroupClasses groupClasses = null;
        if (groupSche.getClassesId() != null) {
            groupClasses = groupClassesService.selectGroupClassesById(groupSche.getClassesId());
        }
        if (groupSche.getClassesName() != null) {
            groupClasses = groupClassesService.selectGroupClassesByName(groupSche.getClassesName());
        }
        if (groupClasses == null) return;
        if (groupClasses == null) return;
        if (StrUtil.isEmpty(groupClasses.getStartTime())) return;
        if (StrUtil.isEmpty(groupClasses.getEndTime())) return;

        Date startDt = DateUtil.parseDateTime(DateUtil.formatDate(groupSche.getScheDate()) + " " + groupClasses.getStartTime());
        Date endDt = DateUtil.parseDateTime(DateUtil.formatDate(groupSche.getScheDate()) + " " + groupClasses.getEndTime());
        if (startDt.getTime() > endDt.getTime()) {
            //看当前时间到底在哪个时间段里，前夜还是后夜
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowDt);
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            if(hour == 23 ) {
                endDt = DateUtil.offset(endDt, DateField.DAY_OF_MONTH, 1);
            }else if(hour <= 7){//到后一天了
                startDt = DateUtil.offset(startDt, DateField.DAY_OF_MONTH, -1);
            }
//            endDt = DateUtil.offset(endDt, DateField.DAY_OF_MONTH, 1);
//            startDt = DateUtil.offset(startDt, DateField.DAY_OF_MONTH, -1);
            groupSche.setScheDate(endDt);
        }
        groupSche.setStartDt(startDt);
        groupSche.setEndDt(endDt);
    }

    @Override
    public boolean checkGroupScheBatch(GroupScheBatchDTO groupScheBatch) {
        Date startDate = groupScheBatch.getStartDate();
        Date endDate = groupScheBatch.getEndDate();
        if (startDate.getTime() > endDate.getTime()) throw new CustomException("开始日期不能大于结束日期");
        List<GroupSche> scheList = groupScheBatch.getScheList();
        for (int i = 0; i < scheList.size(); i++) {
            if (groupScheMapper.checkGroupScheBatch(scheList.get(i).getClassesId(), startDate, endDate) > 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    @Transactional
    public boolean batchDaySche(GroupScheBatchDTO groupScheBatch) {
        Date startDate = groupScheBatch.getStartDate();
        Date endDate = groupScheBatch.getEndDate();
        List<GroupSche> scheList = groupScheBatch.getScheList();
        while (startDate.getTime() <= endDate.getTime()) {
            for (int i = 0; i < scheList.size(); i++) {
                GroupSche sche = new GroupSche();
                sche.setScheDate(startDate);
                sche.setClassesId(scheList.get(i).getClassesId());
                sche.setTeamId(scheList.get(i).getTeamId());
                calTimeGroupSche(sche);
                insertGroupSche(sche);
            }
            startDate = DateUtil.offsetDay(startDate, 1);
        }
        return true;
    }

    @Override
    public boolean setAutoSche(GroupScheAutoDTO groupScheAuto) {
        setAutoScheByCode("initDate", DateUtil.formatDateTime(groupScheAuto.getInitDate()), "初始日期");
        setAutoScheByCode("classesId", Convert.toStr(groupScheAuto.getClassesId()), "初始班次");
        setAutoScheByCode("teamId", Convert.toStr(groupScheAuto.getTeamId()), "初始班组");
        setAutoScheByCode("autoScheEnable", Convert.toStr(groupScheAuto.getAutoScheEnable()), "自动排班启用");
        return true;
    }

    private void setAutoScheByCode(String key, String value, String name) {
        String result = sysConfigService.selectConfigByKey(key);
        if (StrUtil.isEmpty(result)) {
            SysConfig sysConfig = new SysConfig();
            sysConfig.setConfigName(name);
            sysConfig.setRemark("自动排班");
            sysConfig.setConfigKey(key);
            sysConfig.setConfigValue(value);
            sysConfig.setConfigType("Y");
            sysConfigService.insertConfig(sysConfig);
        } else {
            sysConfigService.setConfigValueByKey(key, value);
        }
    }

    @Override
    public GroupScheAutoDTO getAutoSche() {
        GroupScheAutoDTO res = new GroupScheAutoDTO();
        String initDate = sysConfigService.selectConfigByKey("initDate");
        if (StrUtil.isNotEmpty(initDate)) {
            res.setInitDate(DateUtil.parseDateTime(initDate));
        }
        String classesId = sysConfigService.selectConfigByKey("classesId");
        if (StrUtil.isNotEmpty(classesId)) {
            res.setClassesId(Convert.toLong(classesId));
        }
        String teamId = sysConfigService.selectConfigByKey("teamId");
        if (StrUtil.isNotEmpty(teamId)) {
            res.setTeamId(Convert.toLong(teamId));
        }
        String autoScheEnable = sysConfigService.selectConfigByKey("autoScheEnable");
        res.setAutoScheEnable(Convert.toInt(autoScheEnable, 0));
        return res;
    }

    @Override
    public GroupSche getGroupScheByDt(Date dt) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.le("start_dt", dt);
        queryWrapper.gt("end_dt", dt);
        queryWrapper.last("LIMIT 1");
        GroupSche res = groupScheMapper.selectOne(queryWrapper);
        if (res != null) {
            res.setClasses(groupClassesService.selectGroupClassesById(res.getClassesId()));
            res.setTeam(groupTeamService.selectGroupTeamById(res.getTeamId()));
            if (res.getClasses() != null) {
                res.setClassesName(res.getClasses().getClassesName());
                res.setClassesCode(res.getClasses().getCode());
            }
            if (res.getTeam() != null) {
                res.setTeamName(res.getTeam().getTeamName());
                res.setTeamCode(res.getTeam().getCode());
            }
        }
        return res;
    }

    @Override
    public GroupSche getGroupScheByClasses(Date scheDate, Long classesId) {
        return groupScheMapper.getGroupScheByClasses(scheDate, classesId);
    }


}
